Completed
Push — master ( 8ee61c...d11c3b )
by Ekin
02:12
created

main.js ➔ playFromQueueExchange2   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 10
rs 8.8571
c 1
b 0
f 0
cc 6
nc 3
nop 0
1
var eventQueue = [];
2
var svg;
3
var element;
4
var drawingArea;
5
var width;
6
var height;
7
var volume = 0.6;
8
var ULTIMATE_DREAM_KILLER = false;  // https://github.com/debugger22/github-audio/pull/19
9
var orgRepoFilterNames = [];
10
var header = $('header');
11
12
var scale_factor = 6,
13
    note_overlap = 2,
14
    note_timeout = 300,
15
    current_notes = 0,
16
    max_life = 20000;
17
18
var svg_background_color_online  = 'black',
19
    svg_background_color_offline = 'black',
20
    svg_text_color               = '#FFFFFF',
21
    edit_color                   = '#FFFFFF',
22
    total_sounds = 51;
23
24
var celesta = [],
25
    clav = [],
26
    swells = [],
27
    all_loaded = false;
28
29
var socket = new WebSocket("ws://localhost:1337/ws");
30
31
socket.addEventListener("message", function (data) {
32
    var json = JSON.parse(data.data);
33
34
    if (json.hasOwnProperty('connectedUsers')) {
35
        $('.online-users-count').html(json.connectedUsers);
36
37
        return;
38
    }
39
40
    json.forEach(function (event) {
41
        if (!isEventInQueue(event)) {
42
            // Filter out events only specified by the user
43
            if (orgRepoFilterNames != []) {
44
                // Don't consider pushes to github.io repos when org filter is on
45
                if (new RegExp(orgRepoFilterNames.join("|")).test(event.repoName) && event.repoName.indexOf('github.io') == -1) {
46
                    eventQueue.push(event);
47
                }
48
            } else {
49
                eventQueue.push(event);
50
            }
51
        }
52
    });
53
54
    // Don't let the eventQueue grow more than 1000
55
    if (eventQueue.length > 1000) eventQueue = eventQueue.slice(0, 1000);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
56
});
57
58
socket.onopen = function(e){
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
59
    $('svg').css('background-color', svg_background_color_online);
60
    header.css('background-color', svg_background_color_online);
61
    $('.offline-text').css('visibility', 'hidden');
62
    $('.events-remaining-text').css('visibility', 'visible');
63
    $('.events-remaining-value').css('visibility', 'visible');
64
    $('.online-users-div').css('visibility', 'visible');
65
};
66
67
socket.onclose = function(e){
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
68
    $('svg').css('background-color', svg_background_color_offline);
69
    header.css('background-color', svg_background_color_offline);
70
    $('.offline-text').css('visibility', 'visible');
71
    $('.events-remaining-text').css('visibility', 'visible');
72
    $('.events-remaining-value').css('visibility', 'visible');
73
};
74
75
socket.onerror = function(e){
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
76
    $('svg').css('background-color', svg_background_color_offline);
77
    header.css('background-color', svg_background_color_offline);
78
    $('.offline-text').css('visibility', 'visible');
79
    $('.events-remaining-text').css('visibility', 'visible');
80
    $('.events-remaining-value').css('visibility', 'visible');
81
};
82
83
/**
84
* This function checks whether an event is already in the queue
85
*/
86
function isEventInQueue(event){
87
  for(var i=0; i<eventQueue.length; i++){
88
    if(eventQueue[i].id == event.id)
89
      return true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
90
  }
91
  return false;
92
}
93
94
/**
95
 * This function adds a filter for events that we don't want to hear.
96
 *
97
 * To extend this function, simply add return true for events that should be filtered.
98
 */
99
function shouldEventBeIgnored(event){
100
  // This adds an easter egg to only play closed PRs
101
  if (!!ULTIMATE_DREAM_KILLER)
102
    return (event.type !== "PullRequestEvent" || event.action !== "closed");
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
103
104
  return false;
105
}
106
107
$(function(){
108
  element = document.documentElement;
109
  drawingArea = document.getElementsByTagName('#area')[0];
110
  width  = window.innerWidth || element.clientWidth || drawingArea.clientWidth;
111
  height = (window.innerHeight - header.height()) || (element.clientHeight - header.height()) || (drawingArea.clientHeight - header.height());
112
  $('svg').css('background-color', svg_background_color_online);
113
  header.css('background-color', svg_background_color_online);
114
  $('svg text').css('color', svg_text_color);
115
  $('#volumeSlider').slider({
116
    'max': 100,
117
    'min': 0,
118
    'value': volume*100,
119
    'slide' : function(event, ui){
120
      volume = ui.value/100.0;
121
      Howler.volume(volume);
0 ignored issues
show
Bug introduced by
The variable Howler seems to be never declared. If this is a global, consider adding a /** global: Howler */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
122
    },
123
    'change' : function(event, ui){
124
      volume = ui.value/100.0;
125
      Howler.volume(volume);
0 ignored issues
show
Bug introduced by
The variable Howler seems to be never declared. If this is a global, consider adding a /** global: Howler */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
126
    }
127
  });
128
129
  // Main drawing area
130
  svg = d3.select("#area").append("svg");
1 ignored issue
show
Bug introduced by
The variable d3 seems to be never declared. If this is a global, consider adding a /** global: d3 */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
131
  svg.attr({width: width, height: height});
132
  svg.style('background-color', svg_background_color_online);
133
134
  // For window resizes
135
  var update_window = function() {
136
      width  = window.innerWidth || element.clientWidth || drawingArea.clientWidth;
137
      height = (window.innerHeight - header.height()) || (element.clientHeight - header.height()) || (drawingArea.clientHeight - header.height());
138
      svg.attr("width", width).attr("height", height);
139
  };
140
  window.onresize = update_window;
141
  update_window();
142
143
  var loaded_sounds = 0;
144
  var sound_load = function(r) {
0 ignored issues
show
Unused Code introduced by
The parameter r is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
145
      loaded_sounds += 1;
146
      if (loaded_sounds == total_sounds) {
147
          all_loaded = true;
148
          setTimeout(playFromQueueExchange1, Math.floor(Math.random() * 1000));
149
          // Starting the second exchange makes music a bad experience
150
      }
151
  };
152
153
  // Load sounds
154
  for (var i = 1; i <= 24; i++) {
155
      if (i > 9) {
156
          fn = 'c0' + i;
0 ignored issues
show
Bug introduced by
The variable fn seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.fn.
Loading history...
157
      } else {
158
          fn = 'c00' + i;
159
      }
160
      celesta.push(new Howl({
0 ignored issues
show
Bug introduced by
The variable Howl seems to be never declared. If this is a global, consider adding a /** global: Howl */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
161
          src : [
162
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/celesta/' + fn + '.ogg',
163
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/celesta/' + fn + '.mp3'
164
          ],
165
          volume : 0.7,
166
          onload : sound_load(),
167
          buffer: true
168
      }));
169
      clav.push(new Howl({
170
          src : [
171
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/clav/' + fn + '.ogg',
172
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/clav/' + fn + '.mp3'
173
          ],
174
          volume : 0.4,
175
          onload : sound_load(),
176
          buffer: true
177
      }))
178
  }
179
180
  for (var i = 1; i <= 3; i++) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 154. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
181
      swells.push(new Howl({
182
          src : [
183
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/swells/swell' + i + '.ogg', 
184
              'https://d1fz9d31zqor6x.cloudfront.net/sounds/swells/swell' + i + '.mp3'
185
          ],
186
          volume : 1,
187
          onload : sound_load(),
188
          buffer: true
189
      }));
190
  }
191
192
  Howler.volume(volume);
0 ignored issues
show
Bug introduced by
The variable Howler seems to be never declared. If this is a global, consider adding a /** global: Howler */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
193
194
  // Make header and footer visible
195
  $('body').css('visibility', 'visible');
196
197
  $('#org-repo-filter-name').on('input', function() {
198
    orgRepoFilterNames = $('#org-repo-filter-name').val().split(' ');
199
    eventQueue = [];
200
  });
201
202
});
203
204
/**
205
* Randomly selects a swell sound and plays it
206
*/
207
function playRandomSwell() {
208
    var index = Math.round(Math.random() * (swells.length - 1));
209
    swells[index].play();
210
}
211
212
/**
213
* Plays a sound(celesta and clav) based on passed parameters
214
*/
215
function playSound(size, type) {
216
    var max_pitch = 100.0;
217
    var log_used = 1.0715307808111486871978099;
218
    var pitch = 100 - Math.min(max_pitch, Math.log(size + log_used) / Math.log(log_used));
219
    var index = Math.floor(pitch / 100.0 * Object.keys(celesta).length);
220
    
221
    index += Math.floor(Math.random() * 4) - 2;
222
    index = Math.min(Object.keys(celesta).length - 1, index);
223
    index = Math.max(1, index);
224
    if (current_notes < note_overlap) {
225
        current_notes++;
226
        if (type == 'IssuesEvent' || type == 'IssueCommentEvent') {
227
            clav[index].play();
228
        } else if(type == 'PushEvent') {
229
            celesta[index].play();
230
        }else{
231
          playRandomSwell();
232
        }
233
        setTimeout(function() {
234
            current_notes--;
235
        }, note_timeout);
236
    }
237
}
238
239
// Following are the n numbers of event consumers
240
// consuming n events each per second with a random delay between them
241
242
function playFromQueueExchange1(){
243
  var event = eventQueue.shift();
244
  if(event != null && event.message != null && !shouldEventBeIgnored(event) && svg != null){
245
    playSound(event.message.length*1.1, event.type);
246
    if(!document.hidden)
247
      drawEvent(event, svg);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
248
  }
249
  setTimeout(playFromQueueExchange1, Math.floor(Math.random() * 1000) + 500);
250
  $('.events-remaining-value').html(eventQueue.length);
251
}
252
253
// This method capitalizes the string in place
254
String.prototype.capitalize = function(all){
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type String. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
255
    if(all){
256
      return this.split(' ').map(function(e){
257
        return e.capitalize().join(' ');
258
      });
259
    }else{
260
         return this.charAt(0).toUpperCase() + this.slice(1);
261
    }
262
};
263
264
function drawEvent(data, svg_area) {
265
    var starting_opacity = 1;
266
    var opacity = 1 / (100 / data.message.length);
267
    if (opacity > 0.5) opacity = 0.5;
0 ignored issues
show
Unused Code introduced by
The assignment to variable opacity seems to be never used. Consider removing it.
Loading history...
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
268
269
    var size = data.message.length;
270
    var label_text;
271
    var ring_radius = 80;
272
    var ring_anim_duration = 3000;
273
    svg_text_color = '#FFFFFF';
274
275
    switch(data.type){
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
276
      case "PushEvent":
277
        label_text = data.actorName.capitalize() + " pushed to " + data.repoName;
278
        edit_color = '#22B65D';
279
      break;
280
      case "PullRequestEvent":
281
        label_text = data.actorName.capitalize() + " " +
282
          data.action + " " + " a PR for " + data.repoName;
283
          edit_color = '#8F19BB';
284
          ring_anim_duration = 10000;
285
          ring_radius = 600;
286
      break;
287
      case "IssuesEvent":
288
        label_text = data.actorName.capitalize() + " " +
289
          data.action + " an issue in " + data.repoName;
290
          edit_color = '#ADD913';
291
      break;
292
      case "IssueCommentEvent":
293
        label_text = data.actorName.capitalize() + " commented in " + data.repoName;
294
        edit_color = '#FF4901';
295
      break;
296
      case "ForkEvent":
297
        label_text = data.actorName.capitalize() + " forked " + data.repoName;
298
        edit_color = '#0184FF';
299
        break;
300
      case "CreateEvent":
301
        label_text = data.actorName.capitalize() + " created " + data.repoName;
302
        edit_color = '#00C0C0';
303
      break;
304
      case "WatchEvent":
305
        label_text = data.actorName.capitalize() + " watched " + data.repoName;
306
        edit_color = '#E60062';
307
      break;
308
    }
309
310
    var no_label = false;
0 ignored issues
show
Unused Code introduced by
The variable no_label seems to be never used. Consider removing it.
Loading history...
311
    var type = data.type;
312
313
    var abs_size = Math.abs(size);
314
    size = Math.max(Math.sqrt(abs_size) * scale_factor, 3);
315
316
    Math.seedrandom(data.message);
317
    var x = Math.random() * (width - size) + size;
318
    var y = Math.random() * (height - size) + size;
319
320
    var circle_group = svg_area.append('g')
321
        .attr('transform', 'translate(' + x + ', ' + y + ')')
322
        .attr('fill', edit_color)
323
        .style('opacity', starting_opacity);
324
325
    var ring = circle_group.append('circle');
326
    ring.attr({r: size, stroke: 'none'});
327
    ring.transition()
328
        .attr('r', size + ring_radius)
329
        .style('opacity', 0)
330
        .ease(Math.sqrt)
331
        .duration(ring_anim_duration)
332
        .remove();
333
334
    var circle_container = circle_group.append('a');
335
    circle_container.attr('xlink:href', data.eventURL);
336
    circle_container.attr('target', '_blank');
337
    circle_container.attr('fill', svg_text_color);
338
339
    var circle = circle_container.append('circle');
340
    circle.classed(type, true);
341
    circle.attr('r', size)
342
      .attr('fill', edit_color)
343
      .transition()
344
      .duration(max_life)
345
      .style('opacity', 0)
346
      .remove();
347
348
    circle_container.on('mouseover', function() {
349
      circle_container.append('text')
350
          .text(label_text)
0 ignored issues
show
Bug introduced by
The variable label_text seems to not be initialized for all possible execution paths. Are you sure text handles undefined variables?
Loading history...
351
          .classed('label', true)
352
          .attr('text-anchor', 'middle')
353
          .attr('font-size', '0.8em')
354
          .transition()
355
          .delay(1000)
356
          .style('opacity', 0)
357
          .duration(2000)
358
          .each(function() { no_label = true; })
0 ignored issues
show
Unused Code introduced by
The variable no_label seems to be never used. Consider removing it.
Loading history...
359
          .remove();
360
    });
361
362
    var text = circle_container.append('text')
363
        .text(label_text)
0 ignored issues
show
Bug introduced by
The variable label_text seems to not be initialized for all possible execution paths. Are you sure text handles undefined variables?
Loading history...
364
        .classed('article-label', true)
365
        .attr('text-anchor', 'middle')
366
        .attr('font-size', '0.8em')
367
        .transition()
368
        .delay(2000)
369
        .style('opacity', 0)
370
        .duration(5000)
371
        .each(function() { no_label = true; })
0 ignored issues
show
Unused Code introduced by
The variable no_label seems to be never used. Consider removing it.
Loading history...
372
        .remove();
373
374
  // Remove HTML of decayed events
375
  // Keep it less than 50
376
  if($('#area svg g').length > 50){
377
    $('#area svg g:lt(10)').remove();
378
  }
379
}
380